package top.java.annotationTest;

import org.junit.Test;

import java.lang.annotation.*;

import static java.lang.annotation.ElementType.*;

/**
 *         注解
 *
 *         框架 = 注解 + 反射 + 设计模式
 */
public class AnnotationTest1 {

    /**
     *      JDK 的元 Annotation 用于修饰其他 Annotation 定义
     *
     *      JDK5.0提供了4个标准的meta-annotation类型(元注解)，分别是：
     *
     *       Retention              用于指定该 Annotation 的生命周期  SOURCE/CLASS(默认)/RUNTIME
     *                              只有声明为RUNTIME声明周期的注解，才能通过反射获取
     *
     *       Target                 用于指定被修饰的 Annotation 能用于修饰哪些程序元素。
     *
     *       *************下面两个出现的频率较低
     *
     *       Documented             用于指定被该元 Annotation 修饰的 Annotation 类将被
     *                              javadoc 工具提取成文档。默认情况下，javadoc是不包括注解的。
     *
     *       Inherited              被它修饰的 Annotation 将具有继承性。如果某个类使用了被
     *                              @Inherited 修饰的 Annotation, 则其子类将自动具有该注解。
     */

    @Test
    public void test1() {
        //通过反射获取注解
        Class<Student> studentClass = Student.class;
        Annotation[] annotations = studentClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);    //@top.stmo.annotationTest.MyAnnotation(value=hi)
        }
    }
//    @SuppressWarnings()
}

/**
 *       如何自定义注解
 *
 *       参照@SuppressWarnings定义
 *       1.注解声明为 @interface
 *       2.内部定义成员，通常使用value表示
 *       3.可以指定成员的默认值，使用default定义
 *       4.如果自定义注解没有成员，表明是一个标识作用
 *
 *       自定义注解通常都会指明两个元注解，Retention(指明生命周期)，Target(指明可以修饰的结构)
 *
 */
@Inherited
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) //指定该注解可以修饰的结构
@Retention(RetentionPolicy.RUNTIME)         //指定该 Annotation 的生命周期
@interface MyAnnotation {
//    String value();
    String value() default "hello";         //指定默认值,使用default定义
}

@MyAnnotation(value = "hi")
class Person {

}

class Student extends Person {

}